package com.ft.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ft.dao.NongsukeDao;
import com.ft.domain.Lostarticle;
import com.ft.domain.Nongsuke;
import com.ft.domain.Tzmarket;
import com.ft.service.INongsukeService;
import com.ft.utils.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
/**
 * @Author: ft
 * @Date: 2023/02/08/10:33
 * @Description:
 */
public class NongsukeServiceImpl extends ServiceImpl<NongsukeDao, Nongsuke> implements INongsukeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private NongsukeDao nongsukeDao;

    //增加商品
    @Override
    public int addNongsuke(Nongsuke nongsuke) throws IllegalAccessException {
        /**
         * 先存redis,在存数据库，最后存数据库成功后进行校验，保证数据库和redis里都有数据并且一致
         *  1.封装订单编号，存入tzmarketIdZset所有订单集合中
         *  oldBuyOrderId: 获取添加Zset前的个数
         *  id ：订单id
         */
        Long oldTzmarketId = redisTemplate.opsForZSet().zCard("nongsukeId");
        String id = String.valueOf(nongsuke.getId());
        redisTemplate.opsForZSet().add("nongsukeId",id,1);
        /**
         *  3.封装订单信息，存入Hsah里
         *  格式：订单类型 : 用户id : 订单号
         *  orderKey1：封装hash的key值
         *  stringObjectMap：得到对象属性的map集合
         */
        String orderKey1 = "nongsuke:"+nongsuke.getId ();
        Map<String, Object> stringObjectMap = ObjectUtils.objectToMap (nongsuke);
        redisTemplate.opsForHash ().putAll (orderKey1, stringObjectMap);
        /**
         * 4.将数据存入数据库
         */
        int NongsukeOrder = nongsukeDao.addNongsuke (nongsuke);
        /**
         * 数据校验，保证数据一致性
         * newBuyOrderId：获取添加后的所有订单的Zset个数
         * newlistsize:添加后的用户未付款list集合长度
         * hashOrderStr：获取存入redis的数据
         * hashOrderSize ：订单表所有字段的和
         */
        if (NongsukeOrder == 1 ){
            while (true){
                Long newBuyOrderId = redisTemplate.opsForZSet().zCard("nongsukeId");
                Long  hashOrderSize = redisTemplate.opsForHash().size (orderKey1);
                //结束条件
                if(newBuyOrderId > oldTzmarketId  & hashOrderSize == Nongsuke.total){
                    break;
                }
                //对存入订单id进行校验
                if(newBuyOrderId <= oldTzmarketId){
                    redisTemplate.opsForZSet().add("nongsukeId",id,1);
                    continue;
                }
                //对hash订单表进行校验

                if(hashOrderSize != Nongsuke.total){
                    //移除key
                    redisTemplate.delete (orderKey1);
                    //重新添加
                    Map<String, Object> stringObjectMap1 = ObjectUtils.objectToMap (nongsuke);
                    Set mapkey1 = stringObjectMap.keySet ();
                    for(Object key : mapkey1){
                        redisTemplate.opsForHash().put(orderKey1,key,stringObjectMap.get (key));
                    }
                }
            }
            //将用户发布的商品存入用户发布的商品集合
            String key2 = nongsuke.getIssueUser() + ":issuenongsukegoods";
            redisTemplate.boundSetOps(key2).add(nongsuke.getId());
            //同步订单创建时间
            redisTemplate.opsForHash().delete(orderKey1,"createTime");
            String time = nongsukeDao.getcreateTime (nongsuke.getId ());
            System.out.println ("time:"+time);
            redisTemplate.opsForHash().put(orderKey1,"createTime",time);
            return 1;
        }else {
            //存入数据库失败，删除缓存数据
            redisTemplate.boundZSetOps ("nongsukeId").remove (id);
            redisTemplate.delete (orderKey1);
            return 0;
        }
    }
    //更加id查询商品所有信息
    @Override
    public Nongsuke getNongsuke(Long id) {
        Nongsuke nongsuke = nongsukeDao.selectNongsuke (id);
        return nongsuke;
    }
    /**
     * 查询用于支付订单的信息
     * @param id 订单id
     * @return
     */
    @Override
    public Nongsuke selectNongsukeToPay(Long id) {
        Nongsuke nongsuke = nongsukeDao.selectNongsukeToPay (id);
        return nongsuke;
    }

    /**
     * 付款后，修改订单状态
     * @return 返回受影响的结果
     */
    @Override
    public int updataOrder(int state,String id,int userid) {
        int i = nongsukeDao.updataOrder (state,id);
        String key ="nongsuke:"+id;
        if(i == 1){
            //将订单类型zet集合中的对应订单id的score值加1
            redisTemplate.opsForZSet().incrementScore ("nongsukeId",id,1);
            //修改订单hash表state状态
            redisTemplate.opsForHash().delete(key,state);
            redisTemplate.opsForHash().put(key,"state",1);
            //更新订单时间
            redisTemplate.opsForHash().delete(key,"updateTime");
            String time = nongsukeDao.getupdateTime(Long.valueOf (id));
            redisTemplate.opsForHash().put(key,"updateTime",time);
            return 1;
        }else {
            return 0;
        }
    }
    /**
     * 助农服务分页获取订单数据
     * @param page
     * @return
     */
    @Override
    public List getOrder(int type, int page) {
        //同类型的集合数据
        List resulttype = new ArrayList ();
        //返回的数据
        List result = new ArrayList ();
        //获取所有订单数据
        Set tzmarketId = redisTemplate.opsForZSet ().reverseRangeByScore("nongsukeId", 1, 999);
        //遍历set获取同类型的数据
        for(Object le : tzmarketId){
            Map entries = redisTemplate.opsForHash ().entries ("nongsuke:" + le);
            int T = (int) entries.get ("type");
            int state = (int) entries.get("state");
            if(T == type + 1 & state == 1){
                //对id进行处理
                Object id = entries.get ("id");
                entries.put ("id",""+id);
                resulttype.add (entries);
            }
        }
        //如果数据小于5的情况
        if(resulttype.size() < 5){
            for(int i = 0;i < resulttype.size(); i++){
                //将map转成对象
                result.add (JSONObject.parseObject(JSONObject.toJSONString(resulttype.get(i)), Nongsuke.class));
            }
            return result;
        }else {
            //每次返回5个数据，total：获取数据结束的位置
            int total = 0;
            //每次获取数据循环开始的位置
            int num = page * 5;
            if(page == 0){
                total = 5;
            }else {
                total = (page+1) * 5;
            }
            for (;num < total & num < resulttype.size(); num++){
                Nongsuke lostarticle = JSONObject.parseObject (JSONObject.toJSONString (resulttype.get (num)), Nongsuke.class);
                result.add (lostarticle);
            }
            return result;
        }
    }

    /**
     * 搜索内容
     * @param content 搜索的数据
     * @return
     */
    @Override
    public List search(String content,int type,int page) {
        //返回结果集合
        List result = new ArrayList ();
        //获取订单数据
        Set buyorderId = redisTemplate.opsForZSet ().reverseRangeByScore("nongsukeId", 1, 999);
        //遍历集合取出数据
        for(Object key : buyorderId){
            Map entries = redisTemplate.opsForHash ().entries ("nongsuke:" + key);
            String ct = (String) entries.get ("content");
            Integer type1 = (Integer) entries.get ("type");
            int state = (int) entries.get ("state");
            if(type1 == type+1 & ct.contains (content) & state == 1 ){
                //对id进行处理
                Object id = entries.get ("id");
                entries.put ("id",""+id);
                result.add(entries);
            }
        }
        System.out.println("result的大小"+result.size());
        //数据小于5的情况
        if(result.size() < 5){
            return result;
        }else {
            List ids = new ArrayList();
            //每次返回5个数据，total：获取数据结束的位置
            int total = 0;
            //每次获取数据循环开始的位置
            int num = page * 5;
            if(page == 0){
                total = 5;
            }else {
                total = (page+1) * 5;
            }
            for(;num < total & num < result.size (); num++){
                ids.add (result.get(num));
            }
            return ids;
        }
    }

    /**
     * 查询单个订单信息
     */
    @Override
    public Nongsuke getNongsukeByIdAndOne(String id){
        Nongsuke nongsuke = nongsukeDao.selectNongsuke(Long.valueOf(id));
        return nongsuke;
    }

    /**
     * 获取用户发布的所有商品数据
     * @param userid
     * @return
     */
    @Override
    public List getUserIssueOrderList(int userid){
        //返回结果集合
        List result = new ArrayList();
        //获取所有订单数据
        Set buyorderId = redisTemplate.boundSetOps(userid+":issuenongsukegoods").members();
        List ids = new ArrayList<>(buyorderId);
        //获取订单数据返回
        for (int i = 0; i < ids.size(); i++) {
            Map entries = redisTemplate.opsForHash().entries("nongsuke:" + ids.get(i));
            //对订单号处理成字符串，防止前端精度丢失
            Object id = entries.get("id");
            entries.put("id", "" + id);
            result.add(entries);
        }
        return result;
    }


}
